/**
 * 
 */
package dms.model.role.wrapper;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import dms.dto.StudentAffairTeacherDTO;
import dms.dto.StudentDTO;
import dms.model.Classes;
import dms.model.Dormitory;
import dms.model.Faculty;
import dms.model.School;
import dms.model.exception.NoPermissionException;
import dms.model.exception.NoSuchEntityException;
import dms.model.form.DormitoryChange;
import dms.model.role.Account;
import dms.model.role.Role;
import dms.model.role.Student;
import dms.model.role.StudentAffairTeacher;
import dms.model.role.SystemAdministrator;
import dms.repository.DormitoryChangeRepository;
import dms.repository.DormitoryRepository;
import dms.repository.SchoolRepository;
import dms.repository.StudentRepository;
import dms.repository.SystemAdministratorRepository;
import dms.util.PasswordUtil;

/**
 * 学工处老师的包装类，业务操作封装在此类中，实体数据在变量studentAffairTeacher
 * 中，该类中的许多操作要用到实体数据，该类首先被注入，才能使用，通过BeanFactory
 * 获取
 * @author 李健
 *
 */
public class StudentAffairTeacherWrapper {
	
	private StudentAffairTeacher studentAffairTeacher = null;
	private static final Log log = LogFactory.getLog(StudentAffairTeacherWrapper.class);

	//学工处老师用到的仓储
	private StudentRepository studentRepository = null;
	private DormitoryRepository dormitoryRepository = null;
	private SystemAdministratorRepository systemAdministratorRepository = null;
	private SchoolRepository schoolRepository = null;
	private DormitoryChangeRepository dormitoryChangeRepository = null;
	
	// Domain operation 
	public Student addStudent(StudentDTO studentInfo) throws NoPermissionException {
		Classes classes = this.schoolRepository.findClassesById(studentInfo.getClasses());
		Faculty faculty = classes.getFaculty();
		School school = faculty.getSchool();
		
		//如果该老师增加的学生不是他学院的则不添加
		if (!school.getId().equals(this.getStudentAffairTeacher().getSchool().getId())) {
			throw new NoPermissionException("学生与老师学院不一致");
		}
		Student student = new Student();
		Account account = new Account(Role.STUDENT);
		Dormitory dormitory = this.dormitoryRepository.findById(studentInfo.getDormitory());
		
		try {
			BeanUtils.copyProperties(account, studentInfo);
		} catch (IllegalAccessException e) {
			
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			
			e.printStackTrace();
		}
		
		Date date = new Date();
		account.setRegisterDate(date);
		account.setModifyDate(date);
		account.setId(null);
		account.setPassword(PasswordUtil.MD5Digest(studentInfo.getPassword()));
		
		student.setClasses(classes);
		student.setDormitory(dormitory);
		student.setFaculty(faculty);
		student.setGender('M');
		student.setSchool(school);
		student.setStudentNumber(studentInfo.getStudentNumber());
		
		student.setId(null);
		student.setAccount(account);
		
		return this.studentRepository.createStudent(student);
	}
	
	public Student updateStudent(StudentDTO studentInfo) throws NoPermissionException, NoSuchEntityException {
		Student student = this.studentRepository.findById(studentInfo.getId());
		
		if (student == null) {
			throw new NoSuchEntityException("没有该学生");
		}
		Account account = student.getAccount();
		
		Classes classes = this.schoolRepository.findClassesById(studentInfo.getClasses());
		Faculty faculty = classes.getFaculty();
		School school = faculty.getSchool();
		
		//如果该老师修改的学生不是他学院的则不添加
		if (!school.getId().equals(this.getStudentAffairTeacher().getSchool().getId())) {
			throw new NoPermissionException("学生与老师学院不一致");
		}
		
		Dormitory dormitory = this.dormitoryRepository.findById(studentInfo.getDormitory());
		
		if (dormitory == null) {
			throw new NoSuchEntityException("没有该寝室");
		}
		
		if (studentInfo.getEmail() != null) {
			account.setEmail(studentInfo.getEmail());
		}
		Date date = new Date();
	
		account.setModifyDate(date);
		account.setPassword(PasswordUtil.MD5Digest(studentInfo.getPassword()));

		student.setClasses(classes);
		student.setDormitory(dormitory);
		student.setFaculty(faculty);
		student.setSchool(school);
		student.setStudentNumber(studentInfo.getStudentNumber());
		
		return this.studentRepository.updateStudent(student);
	}
	
	public void deleteStudentById(Long id) throws NoPermissionException {
		Student student  =this.studentRepository.findById(id);
		
		//如果该学生是这个学院，老师有权删除
		if (student.getSchool().getId().equals(this.getStudentAffairTeacher().getSchool().getId())) {
			this.studentRepository.deleteById(id);
		} else {
			throw new NoPermissionException("学生与老师学院不一致");
		}
		
	}
	
	public void processDormitoryChange(DormitoryChange dormitoryChange) throws Exception {
		
		//这里的问题是懒加载时动态代理只支持getClass和getId,equals hashCode不支持
		if (!dormitoryChange.getStudent().getSchool().getId().equals(this.getStudentAffairTeacher().getSchool().getId())) {
			throw new NoPermissionException("学生与老师学院不一致");
		}
		dormitoryChange.process();
		this.dormitoryChangeRepository.updateDormitoryChange(dormitoryChange);
	}
	
	public void applyDormitoryChange(DormitoryChange dormitoryChange) throws Exception {
		
		if (!dormitoryChange.getStudent().getSchool().getId().equals(this.getStudentAffairTeacher().getSchool().getId())) {
			throw new NoPermissionException("学生与老师学院不一致");
		}
		dormitoryChange.apply();
		this.dormitoryChangeRepository.updateDormitoryChange(dormitoryChange);
	}
	
	public void changeStudentPassword(Student student, String newPassword) throws NoPermissionException {
		if (student.getSchool().getId().equals(this.getStudentAffairTeacher().getSchool().getId())) {
			student.getAccount().setPassword(newPassword);
			this.studentRepository.updateStudent(student);
		} else {
			throw new NoPermissionException("学生与老师学院不一致");
		}
			
	}
	
	public void changePassword(String oldPassword, String newPassword) throws NoPermissionException {
		if (oldPassword.equals(this.getStudentAffairTeacher().getAccount().getPassword())) {
			this.getStudentAffairTeacher().getAccount().setPassword(newPassword);
			this.getStudentAffairTeacher().getAccount().setModifyDate(new Date());
			this.systemAdministratorRepository.updateStduentAffairTeacher(this.getStudentAffairTeacher());
		} else {
			throw new NoPermissionException("原始密码错误，无权修改密码");
		}
	}
	
	public void modifyPersonalInfo(StudentAffairTeacherDTO studentAffairTeacherInfo) throws NoPermissionException {
		
		if (!studentAffairTeacherInfo.getId().equals(this.getStudentAffairTeacher().getId())) {
			throw new NoPermissionException("你无权修改这个用户");
		}
		
		if (studentAffairTeacherInfo.getOldEmail() != null && studentAffairTeacherInfo.getEmail() != null) {
			if (studentAffairTeacherInfo.getOldEmail().equals(this.getStudentAffairTeacher().getAccount().getEmail())) {
				this.getStudentAffairTeacher().getAccount().setEmail(studentAffairTeacherInfo.getEmail());
			}
		}
		
		if (studentAffairTeacherInfo.getOldPassword() != null && studentAffairTeacherInfo.getPassword() != null) {
			String oldPassword = PasswordUtil.MD5Digest(studentAffairTeacherInfo.getOldPassword());
			if (oldPassword.equals(this.getStudentAffairTeacher().getAccount().getPassword())) {
				this.getStudentAffairTeacher().getAccount().setPassword(studentAffairTeacherInfo.getPassword());
			}
		}		
		
		if (studentAffairTeacherInfo.getTelephone() != null) {
			this.getStudentAffairTeacher().getAccount().setTelephone(studentAffairTeacherInfo.getTelephone());
		}
		//记住要修改modifyDate
		this.getStudentAffairTeacher().getAccount().setModifyDate(new Date());	
		
		this.systemAdministratorRepository.updateStduentAffairTeacher(this.getStudentAffairTeacher());
	}

	/**
	 * @return the studentAffairTeacher
	 */
	public StudentAffairTeacher getStudentAffairTeacher() {
		return studentAffairTeacher;
	}

	/**
	 * @param studentAffairTeacher the studentAffairTeacher to set
	 */
	public void setStudentAffairTeacher(StudentAffairTeacher studentAffairTeacher) {
		this.studentAffairTeacher = studentAffairTeacher;
	}

	/**
	 * @return the studentRepository
	 */
	public StudentRepository getStudentRepository() {
		return studentRepository;
	}

	/**
	 * @param studentRepository the studentRepository to set
	 */
	public void setStudentRepository(StudentRepository studentRepository) {
		this.studentRepository = studentRepository;
	}

	/**
	 * @return the dormitoryRepository
	 */
	public DormitoryRepository getDormitoryRepository() {
		return dormitoryRepository;
	}

	/**
	 * @param dormitoryRepository the dormitoryRepository to set
	 */
	public void setDormitoryRepository(DormitoryRepository dormitoryRepository) {
		this.dormitoryRepository = dormitoryRepository;
	}

	/**
	 * @return the systemAdministratorRepository
	 */
	public SystemAdministratorRepository getSystemAdministratorRepository() {
		return systemAdministratorRepository;
	}

	/**
	 * @param systemAdministratorRepository the systemAdministratorRepository to set
	 */
	public void setSystemAdministratorRepository(
			SystemAdministratorRepository systemAdministratorRepository) {
		this.systemAdministratorRepository = systemAdministratorRepository;
	}

	/**
	 * @return the schoolRepository
	 */
	public SchoolRepository getSchoolRepository() {
		return schoolRepository;
	}

	/**
	 * @param schoolRepository the schoolRepository to set
	 */
	public void setSchoolRepository(SchoolRepository schoolRepository) {
		this.schoolRepository = schoolRepository;
	}

	/**
	 * @return the dormitoryChangeRepository
	 */
	public DormitoryChangeRepository getDormitoryChangeRepository() {
		return dormitoryChangeRepository;
	}

	/**
	 * @param dormitoryChangeRepository the dormitoryChangeRepository to set
	 */
	public void setDormitoryChangeRepository(
			DormitoryChangeRepository dormitoryChangeRepository) {
		this.dormitoryChangeRepository = dormitoryChangeRepository;
	}

	/**
	 * @param studentRepository
	 * @param dormitoryRepository
	 * @param systemAdministratorRepository
	 * @param schoolRepository
	 * @param dormitoryChangeRepository
	 */
	public StudentAffairTeacherWrapper(StudentRepository studentRepository,
			DormitoryRepository dormitoryRepository,
			SystemAdministratorRepository systemAdministratorRepository,
			SchoolRepository schoolRepository,
			DormitoryChangeRepository dormitoryChangeRepository) {
		super();
		this.studentRepository = studentRepository;
		this.dormitoryRepository = dormitoryRepository;
		this.systemAdministratorRepository = systemAdministratorRepository;
		this.schoolRepository = schoolRepository;
		this.dormitoryChangeRepository = dormitoryChangeRepository;
	}

	/**
	 * 
	 */
	public StudentAffairTeacherWrapper() {
		super();
	}
}
